home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1997 / MacHack 1997.toast / Hacks / Hacks ’93 / The Regulator 1.4 / main.c next >
C/C++ Source or Header  |  1993-06-04  |  9KB  |  246 lines

  1. /*------------------------------------------------------------------------------
  2. #
  3. #   Apple Developer Technical Support
  4. #
  5. # SmallDaemon
  6. # A small faceless background-only application
  7. #
  8. #   main.c  -   C Source
  9. #
  10. #   Copyright © 1991 Apple Computer, Inc.
  11. #   All rights reserved.
  12. #
  13. #   Versions:   
  14. #               1.0               09/91       C.K. Haun <TR>
  15. #   
  16. #   Components:
  17. #                           main.c
  18. #                           AppleEvents.c
  19. #
  20. # This is a _very_ simple sample showing a do-nothing 
  21. # System 7.0 faceless background application.  
  22. # The main things to note are....
  23. # 1)  Look at the SIZE resource for the flag settings you'll
  24. #  need to let the Finder™ know that you only want to work
  25. #  in the background.
  26. # 2) Notice that you really do have your own heap and your own
  27. #  event loop.  You can do anything a foreground application
  28. #  can do, send AppleEvents, PPC stuff, anything else you'd
  29. #  like EXCEPT a graphic interface.
  30. # 3)  NOTE that no managers are started up.  You cannot start up
  31. #  Window, Menu, Dialogs, or anything else that 
  32. #  deals with the graphic front end.  Just leave them out.
  33. #  You _can_ start up QuickDraw, if you want to use some QuickDraw
  34. #  functions (like offscreen ports), but you CANNOT actually 
  35. #  do any screen drawing.
  36. #
  37. # Of course, a backgrounder can be launched from the Finder™ 
  38. # with a double-click.  However, if you'd like the backgrounder
  39. # to perform some useful service for your main application, driver,
  40. # DA, or whatever, you will want it running all the time.
  41. #  The BEST way to insure this is to install the backgrounder in the
  42. # StartUp Items folder in the system folder.  This will insure that
  43. # it is always launched, and it will also reduce memory fragmentation
  44. # since it will be installed at startup time.  You can search for it
  45. # when you need it with IPCListPorts (see the PPC toolbox documentation).
  46. # Optionally, you can use the LaunchApplication trap to launch it 
  47. # when you need it, and kill it when you're done.  But this could 
  48. # cause some multiFinder heap fragmentation.
  49. #
  50. # And remember, it's a backgrounder, you can't see it.  To kill it
  51. # use TaskIt or ProcDoggie.
  52. #
  53. # ---------------------------------------------------------------
  54. #   Use this sample as a starting point, and adapt its' routines to 
  55. #   meet the specific needs of your project.  
  56. #
  57. ------------------------------------------------------------------------------*/
  58.  
  59. /* This doesn't do much but wait for a quit event.  But, you can expand it */
  60. /* to suit whatever your needs are for a backgrounder.  */
  61. /* Be sure to look at the SIZE resource for this app to see how the */
  62. /* flags should be set for a background-only task */
  63. #include <memory.h>
  64. #include <appleevents.h>
  65. #include <events.h>
  66. #include <types.h>
  67. #include <gestaltequ.h>
  68. #include <SegLoad.h>
  69. #include "pb.h"
  70.  
  71. /* variables */
  72. Boolean gQuit = false;
  73. EventRecord gERecord;
  74. Boolean gHasAppleEvents;
  75. unsigned long gMySleep = 120;  /* long time, long time.  Change this if  */
  76. /* you'd like to do null processing. Just keep in mind that the */
  77. /* user does NOT know that you exist, and if you are eating */
  78. /* up a bunch of time the user will not know why his or her */
  79. /* machine is slowing down. */
  80.  
  81. /* structs */
  82. /* a little struct to install handlers from.  Makes it easier to plug in */
  83. /* new handlers */
  84. struct AEinstalls {
  85.     AEEventClass theClass;
  86.     AEEventID theEvent;
  87.     EventHandlerProcPtr theProc;
  88. };
  89. typedef struct AEinstalls AEinstalls;
  90.  
  91. /* prototypes for this file */
  92. pascal OSErr AEOpenHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
  93. pascal OSErr AEOpenDocHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
  94. pascal OSErr AEPrintHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
  95. pascal OSErr AEQuitHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
  96. void DoHighLevel(EventRecord *AERecord);
  97. void InitAEStuff(void);
  98.  
  99. main()
  100. {
  101.     /* We are NOT initializing any managers.  We're in the background, with no */
  102.     /* face, we can't use windows or dialogs or menus.  If you need to talk to the */
  103.     /* user you can post a notification, or launch an application to communicate */
  104.     /* Passing an AppleEvent in the launchapplication trap could do the */
  105.     /* communication for you. */
  106. #ifdef MPW
  107.     extern void _DataInit();
  108.     
  109.     UnloadSeg((Ptr)_DataInit);
  110. #endif
  111.     InitGraf((Ptr) &qd.thePort);
  112.     /* Routine to install Apple event handlers */
  113.     InitAEStuff();
  114.     
  115.     InitPrefs();        // opens the prefs resource file, reads in the user's times
  116.     
  117.     InitPortableStuff();
  118.  
  119.     /* no nothing but high level events */
  120.     while (gQuit == false) {
  121.         WaitNextEvent(highLevelEventMask, &gERecord, gMySleep, 0);
  122.         CheckForMains();
  123.         switch (gERecord.what) {                    
  124.             case kHighLevelEvent:
  125.             DoHighLevel(&gERecord);
  126.             break;
  127.         }
  128.     }
  129. }
  130.  
  131. /* Here are the AppleEvent handlers for this background-only task. */
  132. /* Since this is a real live application, it can accept and send any */
  133. /* Apple Events you want to send or receive.  */
  134. /* In this case, the only ones that make any sense in this app are */
  135. /* 'oapp' and 'quit' */
  136.  
  137.  
  138. /* InitAEStuff checks for the availability of the AppleEvent Manager and */
  139. /* installs our event handlers. */
  140. /* if the AEM isn't around, we bail. */
  141. void InitAEStuff(void)
  142. {
  143.     static AEinstalls HandlersToInstall[] =  {
  144.          {
  145.             kCoreEventClass, kAEOpenApplication, AEOpenHandler
  146.         },  {
  147.             kCoreEventClass, kAEOpenDocuments, AEOpenDocHandler
  148.         },  {
  149.             kCoreEventClass, kAEQuitApplication, AEQuitHandler
  150.         },  {
  151.             kCoreEventClass, kAEPrintDocuments, AEPrintHandler
  152.         }, 
  153.         /* The above are the four required AppleEvents. */
  154.     };
  155.     
  156.     OSErr aevtErr = noErr;
  157.     long aLong = 0;
  158.     Boolean gHasAppleEvents = false;
  159.     /* Check this machine for AppleEvents.  If they are not here (ie not 7.0)
  160.     *   then we exit */
  161.     gHasAppleEvents = (Gestalt(gestaltAppleEventsAttr, &aLong) == noErr);
  162.     /* The following series of calls installs all our AppleEvent Handlers.
  163.     *   These handlers are added to the application event handler list that 
  164.     *   the AppleEvent manager maintains.  So, whenever an AppleEvent happens
  165.     *   and we call AEProcessEvent, the AppleEvent manager will check our
  166.     *   list of handlers and dispatch to it if there is one.
  167.     */
  168.     if (gHasAppleEvents) {
  169.         register qq;
  170.         for (qq = 0; qq < ((sizeof(HandlersToInstall) / sizeof(AEinstalls))); qq++) {
  171.             aevtErr = AEInstallEventHandler(HandlersToInstall[qq].theClass, HandlersToInstall[qq].theEvent,
  172.                                             HandlersToInstall[qq].theProc, 0, false);
  173.             if (aevtErr) {
  174.                 /* Of course, you can't tell the user why you died directly, since you have no face.  */
  175.                 /* But, you can post a notification from here to let them know. */
  176.                 ExitToShell();                              /* just fail, baby */
  177.             }
  178.         }
  179.     } else {
  180.         ExitToShell();
  181.     }
  182. }
  183.  
  184. /* end InitAEStuff */
  185.  
  186. void DoHighLevel(EventRecord *AERecord)
  187. {
  188.     /* I'm not doing any error handling here because there's not a lot */
  189.     /* I can do, just pass the errors back. */
  190.     AEProcessAppleEvent(AERecord);
  191.     
  192. }
  193.  
  194. /* end DoHighLevel */
  195.  
  196.  
  197. /* This is the standard Open Application event.   */
  198. pascal OSErr AEOpenHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
  199. {
  200. #pragma unused (messagein,reply,refIn)
  201.     /* we of course don't do anything here, since we're background only */
  202.     /* But this was a normal launch, so return noErr */
  203.     return(noErr);
  204. }
  205.  
  206. /* end AEOpenHandler */
  207.  
  208. /* Open Doc, opens our documents. */
  209. /* In this case, of course, you are in the background so you should return an error */
  210. /* here since you're not opening a document. */
  211. /* Of course, you _might_ want to open a doc, but you will probably */
  212. /* confuse the user if you do, since they will see no action as the */
  213. /*  result of their clicking on a document icon. */
  214. pascal OSErr AEOpenDocHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
  215. {
  216. #pragma unused (reply, refIn,messagein)
  217.     /* we of course don't do anything here, so tell the sender that we  */
  218.     /* didn't handle the event */
  219.     return(errAEEventNotHandled);
  220. }
  221.  
  222. /* same logic for printing */
  223. pascal OSErr AEPrintHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
  224. {
  225. #pragma unused (reply,refIn,messagein)
  226.     /* we of course don't do anything here */
  227.     return(errAEEventNotHandled);
  228. }
  229.  
  230. /* Standard Quit event handler, to handle a Quit event from the Finder, for example.  */
  231. /* ••••• DO NOT CALL EXITTOSHELL HERE ••••• or you will never have a happy life.  */
  232. pascal OSErr AEQuitHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
  233. {
  234. #pragma unused (messagein,refIn,reply)
  235.     extern Boolean Quit;
  236.     /*  This does _NOT_ quit, you */
  237.     /* should NEVER quit from an AppleEvent handler.  Calling */
  238.     /* ExitToShell here would blow up the Finder™ */
  239.     SetRest();
  240.     SetSysSleep(gSysSleep);
  241.     SetHDSleep(gHDSleep);
  242.     gQuit = true;
  243.     return(noErr);
  244. }
  245.